#include "LogMessage.hpp"

#include "Thread.hpp"

#include <iostream>
#include <string>

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>

const int BUFFER_SIZE = 512;

sockaddr_in sendTo;
socklen_t lenS = sizeof(sendTo);

void* SendMsg(void* arg) {
  std::string name = ((Thread_name_and_Args*)arg)->_name;
  int sock = *(int*)((Thread_name_and_Args*)arg)->_arg;

  while(1) {
    std::string message;
    std::cerr << "请输入你要发送的数据 ::";
    std::getline(std::cin, message);

    if(message == "quit") {
      break;
    }
    sendto(sock, message.c_str(), message.size(), 0, reinterpret_cast<sockaddr*>(&sendTo), lenS);
  }

  exit(10);
}

void* RecvMsg(void* arg) {
  std::string name = ((Thread_name_and_Args*)arg)->_name;
  int sock = *(int*)((Thread_name_and_Args*)arg)->_arg;
  
  while(1) {
    char buffer[BUFFER_SIZE] = {0};
    sockaddr_in get_IP_port;
    socklen_t lenG = sizeof(get_IP_port);

    ssize_t recv = recvfrom(sock, buffer, BUFFER_SIZE, 0, reinterpret_cast<sockaddr*>(&get_IP_port), &lenG);
    if(recv > 0) {
      buffer[recv] = 0;
      std::cout << std::endl;
      std::cout << buffer << std::endl;
    }
  }

}

void usage(const char* fileName) {
  printf("usage:\n%s IP port\n", fileName);
}

int main(int argc, char* argv[]) {
  if(argc != 3) {
    usage(argv[0]);
    exit(1);
  }

  in_addr_t serverIP = inet_addr(argv[1]);
  in_port_t serverPort = htons(atoi(argv[2]));

  memset(&sendTo, 0, lenS);
  sendTo.sin_family = AF_INET;
  sendTo.sin_addr.s_addr = serverIP;
  sendTo.sin_port = serverPort;

  int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  if(sockfd < 0) {
    LogMessage(FATAL, _F, _L, "client create socket fail:: %s", strerror(errno));
    exit(2);
  }
  Thread sender("sender", SendMsg, &sockfd);
  Thread recver("recver", RecvMsg, &sockfd);
  sender.CreateThread();
  recver.CreateThread();

  sender.JoinThread();
  recver.JoinThread();

  close(sockfd);

  return 0;
}
